package middlewares

import (
	"card/app/logic"
	"card/constant"
	"card/pkg/jwt"
	"card/pkg/response"
	"card/pkg/util"
	"context"
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"net/http"
)

// Package middlewares Gin 中间件

func AuthJWT() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从标头 Authorization:Bearer xxxxx 中获取信息，并验证 JWT 的准确性
		claims, err := jwt.NewJwt().ParseToken(c)
		// JWT 解析失败，有错误发生
		if err != nil {
			if errors.Is(err, jwt.ErrTokenExpired) {
				c.AbortWithStatusJSON(http.StatusOK, gin.H{
					"message": err.Error(),
					"log_id":  util.GetLogId(c.Request.Context()),
					"errno":   constant.TokenExpired,
				})
				return
			} else {
				response.Error(c, err, err.Error())
				c.Abort()
				return
			}
		}
		// JWT 解析成功，设置用户信息
		member, err := logic.NewMember(c).GetMemberById(claims.UserID)
		if err != nil {
			response.Error(c, errors.WithMessage(err, "获取用户失败"))
			c.Abort()
			return
		}
		if member.ID == 0 {
			response.Warn(c, "找不到对应用户，用户可能已删除")
			c.Abort()
			return
		}
		if member.Status == -1 {
			response.Warn(c, "该账户已经被禁用！")
			c.Abort()
			return
		}
		// 将用户信息存入 gin.context 里，后续 auth 包将从这里拿到当前用户数据
		c.Request = c.Request.WithContext(
			context.WithValue(c.Request.Context(), "user_id", member.ID),
		)
		c.Request = c.Request.WithContext(
			context.WithValue(c.Request.Context(), "user", *member),
		)
		c.Next()
	}
}
